package cn.kai.component;

import cn.hutool.core.collection.CollUtil;
import cn.kai.dto.SysMenuTreeDto;
import cn.kai.dto.SysProductExcelDto;
import cn.kai.enums.SysMenuObjectTypeEnums;
import cn.kai.mapper.SysDataMapper;
import cn.kai.mapper.SysMenuMapper;
import cn.kai.mapper.SysMenuRelMapper;
import cn.kai.mapper.SysProductMapper;
import cn.kai.model.SysDataDO;
import cn.kai.model.SysMenuDO;
import cn.kai.model.SysMenuRelDO;
import cn.kai.model.SysProductDO;
import cn.kai.util.ConvertUtils;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 Author: cKnight
 Date: 2025/3/8
 */
@Slf4j
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class ProductExcelListener implements ReadListener<SysProductExcelDto> {

    private List<SysProductExcelDto> cacheList;

    private SysProductMapper sysProductMapper;

    private SysMenuMapper sysMenuMapper;

    private SysMenuRelMapper sysMenuRelMapper;

    private SysDataMapper sysDataMapper;

    @Override
    public void invoke(SysProductExcelDto sysProductExcelDto, AnalysisContext analysisContext) {
        String productInfo = sysProductExcelDto.getProductInfo();
        if (StringUtils.isNotBlank(productInfo) && !cacheList.isEmpty()) {
            saveData();
            cacheList.clear();
        }
        cacheList.add(sysProductExcelDto);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        if (CollUtil.isNotEmpty(cacheList)) {
            saveData();
        }
    }

    private void saveData() {
        SysProductDO sysProductDO = new SysProductDO();
        List<String> menuList = new ArrayList<>();
        for (SysProductExcelDto obj : cacheList) {
            if (StringUtils.isNotBlank(obj.getProductInfo())) {
                String[] split = obj.getProductInfo().split("\\|");
                sysProductDO.setName(split[0]);
                if (StringUtils.isNotBlank(split[1])){
                    sysProductDO.setNo(split[1]);
                }
                sysProductDO.setType(split[2]);
                if (StringUtils.isNotBlank(split[3]) && !"NULL".equals(split[3])){
                    sysProductDO.setDetail(split[3]);
                }
                sysProductMapper.insert(sysProductDO);
            }
            if (StringUtils.isNotBlank(obj.getMenuInfo())) {
                String menuInfo = obj.getMenuInfo();
                if (menuInfo.contains("|") && menuList.isEmpty()) {
                    //直接添加
                    menuList.add(menuInfo);
                    saveMenu(sysProductDO, menuList);
                    menuList.clear();
                } else if ((menuInfo.startsWith("0") || menuInfo.contains("|")) && !menuList.isEmpty()) {
                    menuList.add(menuInfo);
                } else if (!menuInfo.contains("|") && !menuInfo.startsWith("0")) {
                    if (CollUtil.isNotEmpty(menuList)){
                        saveMenu(sysProductDO,menuList);
                    }
                    menuList.clear();
                    //添加
                    menuList.add(menuInfo);
                }
            }
        }
        if (CollUtil.isNotEmpty(menuList)){
            saveMenu(sysProductDO,menuList);
        }
    }

    private void saveMenu(SysProductDO sysProductDO, List<String> menuList) {
        List<SysMenuDO> sysMenuList = new ArrayList<>();
        List<SysDataDO> sysDataList = new ArrayList<>();
        Map<Integer, List<SysMenuTreeDto>> levelMap = new HashMap<>();
        for (String menu : menuList) {
            if (menu.contains("|")) {
                String[] split = menu.split("\\|");
                if (split.length == 3 && "NULL".equals(split[1])) {
                    //直接添加data
                    JSONObject data = JSONObject.parseObject(split[2]);
                    data.forEach((k, v) -> {
                        sysDataList.add(SysDataDO.builder()
                                .dataKey(k)
                                .dataValue(v.toString())
                                .objectId(sysProductDO.getId())
                                .build());
                    });
                    continue;
                }

            }
            int level = 0;
            String name = menu;
            while (name.startsWith("0")) {
                level++;
                name = name.substring(1);
            }
            SysMenuTreeDto node = new SysMenuTreeDto();
            node.setId(IdWorker.getId());
            node.setSort(0);
            node.setParentId(0L);
            node.setChildren(new ArrayList<>());
            node.setName(name);
            if (level == 0){
                //根节点
                levelMap.put(0, new ArrayList<>());
                levelMap.get(0).add(node);
                parseMenu(menu,node,sysDataList);
                sysMenuList.add(toMenu(node));
            }else {
                if (!levelMap.containsKey(level)){
                    levelMap.put(level,new ArrayList<>());
                }
                levelMap.get(level).add(node);
                //获取父节点
                List<SysMenuTreeDto> parentNodes = levelMap.get(level - 1);
                SysMenuTreeDto parent = parentNodes.get(parentNodes.size() - 1);
                //解析menu
                parseMenu(name,node,sysDataList);

                List<SysMenuTreeDto> child = parent.getChildren();
                node.setSort(CollUtil.isEmpty(child) ? 0 : child.get(child.size() - 1).getSort() + 5);
                node.setParentId(parent.getId());
                parent.getChildren().add(node);
                sysMenuList.add(toMenu(node));
            }
        }
        //入库
        if (CollUtil.isNotEmpty(sysMenuList)){
            sysMenuList.forEach(obj->{
                sysMenuMapper.insert(obj);
                SysMenuRelDO relDO = SysMenuRelDO.builder()
                        .menuId(obj.getId())
                        .objectId(sysProductDO.getId())
                        .objectType(SysMenuObjectTypeEnums.PRODUCT.name())
                        .build();
                sysMenuRelMapper.insert(relDO);
            });
        }
        if (CollUtil.isNotEmpty(sysDataList)){
            sysDataList.forEach(obj->sysDataMapper.insert(obj));
        }
    }

    private void parseMenu(String menu, SysMenuTreeDto node, List<SysDataDO> sysDataList) {
        if (menu.contains("|")){
            String[] split = menu.split("\\|");
            if (split.length == 3){
                node.setName(split[0]);
                if (StringUtils.isNotBlank(split[1])){
                    node.setType(split[1]);
                }
                if (StringUtils.isNotBlank(split[2])){
                    JSONObject data = JSONObject.parseObject(split[2]);
                    data.forEach((k, v) -> sysDataList.add(SysDataDO.builder()
                            .dataKey(k)
                            .dataValue(v.toString())
                            .objectId(node.getId())
                            .build()));
                }
            }
        }
    }

    public SysMenuDO toMenu(SysMenuTreeDto sysMenuTreeDto){
        return ConvertUtils.beanProcess(sysMenuTreeDto,SysMenuDO.class);
    }
}
